import numpy as np
import pandas as pd
from typing import Union, List, Tuple

class StockPredictor:
    """股票趋势预测工具类"""
    
    def __init__(self):
        """初始化预测器"""
        pass

    @staticmethod
    def calculate_ma(prices: List[float], window: int) -> List[float]:
        """计算移动平均线
        
        Args:
            prices: 历史价格列表
            window: 移动窗口大小
            
        Returns:
            移动平均线数值列表
        """
        return list(pd.Series(prices).rolling(window=window).mean())

    @staticmethod
    def calculate_rsi(prices: List[float], period: int = 14) -> List[float]:
        """计算相对强弱指标(RSI)
        
        Args:
            prices: 历史价格列表
            period: RSI周期
            
        Returns:
            RSI数值列表
        """
        delta = pd.Series(prices).diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
        
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        return list(rsi)

    def predict_trend(self, 
                     prices: List[float], 
                     ma_short: int = 5, 
                     ma_long: int = 20) -> str:
        """预测价格趋势
        
        Args:
            prices: 历史价格列表
            ma_short: 短期移动平均线周期
            ma_long: 长期移动平均线周期
            
        Returns:
            趋势预测结果: "上涨"/"下跌"/"震荡"
        """
        if len(prices) < ma_long:
            return "数据不足"
            
        # 计算短期和长期移动平均线
        ma_short_values = self.calculate_ma(prices, ma_short)
        ma_long_values = self.calculate_ma(prices, ma_long)
        
        # 计算RSI
        rsi = self.calculate_rsi(prices)
        
        # 获取最新值
        current_ma_short = ma_short_values[-1]
        current_ma_long = ma_long_values[-1]
        current_rsi = rsi[-1]
        
        # 趋势判断逻辑
        if current_ma_short > current_ma_long and current_rsi > 50:
            return "上涨"
        elif current_ma_short < current_ma_long and current_rsi < 50:
            return "下跌"
        else:
            return "震荡"

    def get_support_resistance(self, 
                             prices: List[float], 
                             window: int = 20) -> Tuple[float, float]:
        """计算支撑位和压力位
        
        Args:
            prices: 历史价格列表
            window: 计算窗口
            
        Returns:
            (支撑位, 压力位)元组
        """
        if len(prices) < window:
            return (0, 0)
            
        recent_prices = prices[-window:]
        support = min(recent_prices)
        resistance = max(recent_prices)
        
        return (support, resistance) 